﻿using System;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq;
using TrinityAPI.Base;
using TrinityAPI.Base.Tools;
using TrinityAPI.Base.Models;
using Jd.Api.Request;
using Jd.Api;

namespace JingDong.Open.Platform
{
    public class GetOrderSensitive : IAction
    {
        public JToken Invoke(JObject dataset, params JToken[] args)
        {
            try
            {
                var request = args.Length > 0 ? args[0] as JObject : dataset.GetJsonObject("request");
                var dbOrderInfo = dataset.GetJsonObjectValue("orderinfo");
                var constant = dataset.GetJsonObject("constant");
                var jingdongAPIConfig = constant.GetJsonObject("jingdongAPIConfig");
                
                string orders_nos = request.GetJsonObjectStringValue("orders_nos");
                string eShopCode = request.GetJsonObjectStringValue("token");
                bool decrypt = request.GetJsonObjectBooleanValue("decrypt", true);
                string url = jingdongAPIConfig.GetJsonObjectStringValue("url");
                string appKey = jingdongAPIConfig.GetJsonObjectStringValue("app_key");
                string appSecret = jingdongAPIConfig.GetJsonObjectStringValue("app_secret");

                if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(appKey) || string.IsNullOrWhiteSpace(appSecret))
                    throw new BaseException("@0002", "");

                if (string.IsNullOrWhiteSpace(eShopCode))
                    throw new BaseException("@2002", "");

                if (string.IsNullOrWhiteSpace(orders_nos))
                    throw new BaseException("@2003", "");

                string orderId = orders_nos;

                string accessToken = GetAccessToken.GetToken(eShopCode, constant);

                var client = new DefaultJdClient(url, appKey, appSecret);

                JObject orderInfo = null;
                if (dbOrderInfo != null && dbOrderInfo.Type == JTokenType.Array && dbOrderInfo.HasValues && dbOrderInfo[0] is JObject)
                {
                    orderInfo = JSONHelper.JsonToJObject((dbOrderInfo[0] as JObject).GetJsonObjectStringValue("responseJson"));
                }

                if (orderInfo == null)
                {
                    PopOrderGetRequest orderRequest = new PopOrderGetRequest();
                    orderRequest.orderId = orderId;
                    orderRequest.optionalFields = "orderId,venderId,orderType,consigneeInfo";
                    var orderResponse = client.Execute(orderRequest, accessToken, DateTime.Now.ToLocalTime());

                    if (!orderResponse.IsError)
                    {
                        var orderData = JSONHelper.JsonToJObject(orderResponse.Body);
                        orderInfo = orderData.GetJsonObject("jingdong_pop_order_get_responce").GetJsonObject("orderDetailInfo").GetJsonObject("orderInfo");
                    }
                }

                if (orderInfo == null)
                    throw new BaseException("@2004", "");

                var consigneeInfo = orderInfo.GetJsonObject("consigneeInfo");
                if (consigneeInfo == null)
                    throw new BaseException("@2005", "");

                string fullname = null;
                string fullAddress = null;
                string province = consigneeInfo.GetJsonObjectStringValue("province");
                string city = consigneeInfo.GetJsonObjectStringValue("city");
                string county = consigneeInfo.GetJsonObjectStringValue("county");
                string desen_telephone = consigneeInfo.GetJsonObjectStringValue("desen_telephone");
                string desen_mobile = consigneeInfo.GetJsonObjectStringValue("desen_mobile");
                string oaid = consigneeInfo.GetJsonObjectStringValue("oaid");
                string telephone = null;
                string mobile = null;

                if (constant.GetJsonObjectBooleanValue("ForceOAIDMode"))
                {
                    desen_mobile = null;
                    desen_telephone = null;
                }
                if (string.IsNullOrWhiteSpace(oaid) || !string.IsNullOrWhiteSpace(desen_mobile))
                {
                    oaid = null;
                    var tdeclient = Jd.ACES.TDEClient.GetInstance(url, appKey, appSecret, accessToken);
                    try
                    {
                        fullname = tdeclient.DecryptString(consigneeInfo.GetJsonObjectStringValue("fullname"));
                    }
                    catch (Exception ex)
                    {
                        throw new BaseException("@2006", "");
                    }
                    try
                    {
                        fullAddress = tdeclient.DecryptString(consigneeInfo.GetJsonObjectStringValue("fullAddress"));
                    }
                    catch (Exception ex)
                    {
                        throw new BaseException("@2007", "");
                    }
                }
                else if (decrypt)
                {
                    JArray orderInfos = new JArray();
                    orderInfos.Add(new JObject()
                    {
                        { "orderId", orderId },
                        { "oaid", oaid }
                    });
                    JObject getReceiverInfoListReqVO = constant.GetJsonObject("getReceiverInfoParams") ?? new JObject()
                    {
                        { "orderType", "POP" },
                        { "scenesType", "1001" },
                        { "appName", "TOMS" }
                    };
                    getReceiverInfoListReqVO["orderInfos"] = orderInfos;
                    string apiMethod = "jingdong.jos.order.oaid.decrypt";
                    var receiverResponse = APIRequestHelper.DoRequest(dataset, new JObject() { { "getReceiverInfoListReqVO", getReceiverInfoListReqVO } }, apiMethod, eShopCode, accessToken) as JObject;
                    var receiverInfos = receiverResponse.GetJsonObject("jingdong_jos_order_oaid_decrypt_responce").GetJsonObject("returnType").GetJsonObjectValue("data") as JArray;
                    if (receiverInfos != null && receiverInfos.Count > 0)
                    {
                        var receiverInfo = receiverInfos[0] as JObject;
                        if (receiverInfo != null)
                        {
                            var tdeclient = Jd.ACES.TDEClient.GetInstance(url, appKey, appSecret, accessToken);
                            try
                            {
                                fullname = tdeclient.DecryptString(receiverInfo.GetJsonObjectStringValue("customerName"));
                                if (!string.IsNullOrWhiteSpace(fullname))
                                {
                                    int oriLength = fullname.Length;
                                    fullname = Regex.Replace(fullname, @"[\ufe00\u200d\u202d\u200e\u200c]", string.Empty);
                                    LogHelper.Info(string.Format("CustomerName length:{0}-{1}", oriLength, fullname.Length));
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new BaseException("@2006", "");
                            }
                            try
                            {
                                fullAddress = tdeclient.DecryptString(receiverInfo.GetJsonObjectStringValue("address"));
                                if (!string.IsNullOrWhiteSpace(fullAddress))
                                {
                                    int oriLength = fullAddress.Length;
                                    fullAddress = Regex.Replace(fullAddress, @"[\ufe00\u200d\u202d\u200e\u200c]", string.Empty);
                                    LogHelper.Info(string.Format("FullAddress length:{0}-{1}", oriLength, fullAddress.Length));
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new BaseException("@2007", "");
                            }
                            try
                            {
                                mobile = tdeclient.DecryptString(receiverInfo.GetJsonObjectStringValue("consMobilePhone"));
                                telephone = "";
                            }
                            catch (Exception ex)
                            {
                                throw new BaseException("@2007", "");
                            }
                        }
                    }
                }
                else
                {
                    fullname = consigneeInfo.GetJsonObjectStringValue("fullname");
                    fullAddress = consigneeInfo.GetJsonObjectStringValue("fullAddress");
                    mobile = consigneeInfo.GetJsonObjectStringValue("mobile");
                    telephone = "";
                }

                if (string.IsNullOrWhiteSpace(mobile))
                {
                    if (decrypt)
                    {
                        PopOrderGetmobilelistRequest mobileRequest = new PopOrderGetmobilelistRequest();
                        mobileRequest.appName = constant.GetJsonObject("getReceiverInfoParams").GetJsonObjectStringValue("appName", "TOMS");
                        mobileRequest.orderId = orderId;
                        var mobileResponse = client.Execute(mobileRequest, accessToken, DateTime.Now.ToLocalTime());

                        JObject mobileInfo = null;
                        if (!mobileResponse.IsError)
                        {
                            var mobileData = JSONHelper.JsonToJObject(mobileResponse.Body);
                            mobileInfo = mobileData.GetJsonObject("jingdong_pop_order_getmobilelist_responce").GetJsonObject("result").GetJsonObject("data").GetJsonObject(orderId);
                        }

                        if (mobileInfo == null)
                        {
                            string mobileENC = consigneeInfo.GetJsonObjectStringValue("mobileENC");
                            string phoneENC = consigneeInfo.GetJsonObjectStringValue("phoneENC");
                            if (!string.IsNullOrWhiteSpace(mobileENC) || !string.IsNullOrWhiteSpace(phoneENC))
                            {
                                mobileInfo = new JObject();
                                mobileInfo["customerPhone"] = phoneENC;
                                mobileInfo["consMobilePhone"] = mobileENC;
                            }
                            else
                            {
                                throw new BaseException("@2008", "");
                            }
                        }

                        telephone = mobileInfo.GetJsonObjectStringValue("customerPhone");
                        mobile = mobileInfo.GetJsonObjectStringValue("consMobilePhone");
                    }
                    else
                    {
                        mobile = desen_mobile;
                        telephone = "";
                    }
                }

                //if (string.IsNullOrWhiteSpace(fullname) || string.IsNullOrWhiteSpace(fullAddress) || (string.IsNullOrWhiteSpace(telephone) && string.IsNullOrWhiteSpace(mobile)))
                //    throw new BaseException("@2012", "");

                var response = new JObject();
                response["orders_no"] = orderId;
                response["receiver_name"] = fullname;
                response["receiver_province"] = province;
                response["receiver_city"] = city;
                response["receiver_district"] = county;
                response["receiver_address"] = fullAddress;
                response["receiver_telephone"] = telephone;
                response["receiver_mobile"] = mobile;
                response["desen_telephone"] = desen_telephone;
                response["desen_mobile"] = desen_mobile;
                response["oaid"] = oaid;
                return new JArray() { response };
            }
            catch(BaseException ex)
            {
                if (!string.IsNullOrEmpty(ex.Message))
                    throw ex;
                throw new Exception(ex.Code);
            }
            catch (Exception ex)
            {
                LogHelper.Info("GetOrderSensitive fail: " + ex.Message);
                throw new Exception("@2001");
            }
        }
    }
}
